Rutherford Roof 30MHz Re-channelization Experiment¶

In [1]:
import numpy as np
from numpy.fft import fftfreq,fftshift
import matplotlib.pyplot as plt
import sys
sys.path.append("..") # for pfb tools imports etc

from pfb import forward_pfb,inverse_pfb,quantize_8_bit,quantize_8_bit_real,quantize_8_bit_spec_scaled_per_channel
import conjugate_gradient as cg
In [2]:
# shortcut variables
sqrt=np.sqrt

Global Variables¶

In [3]:
LFRAME=2048        # Length of a U1 frame
NCHAN=LFRAME//2+1  # Number of channels
NTAP=4             # Number of taps
NFRAMES=16000      # Number of frames of data to inspect
NFRAMES_OFFSET=100 # Number of frames to skip at the beginning
SR=10e6            # 10MHz Sample Rate
CF=35e6            # 35MHz Central Frequency 
FNAME="gqrx_20230601_175822_35000000_10000000_fc.raw" 
                   # File name/Relative path to data file ^
ADC_DELTA=0.04     # ADC quantization interval
COMPLEX_DELTA=0.25 # Quantization delta of channelized signal
IMSCALE_PLT=(-2.5,1)# Set scale of spectrogram plot colors
IMSCALE_RES=(-2.5,-1)# Set scale of residual spectrogram colors
CMAP_RES="terrain" # colormap of residual plts, default "gist_rainbow"

Waterfall plotting tool

In [4]:
from mpl_toolkits.axes_grid1 import make_axes_locatable
def waterfall(spec,sr,cf,title=None,imshow_scale=IMSCALE_PLT,
              cmap="gist_rainbow"):
    """Waterfall plot.
    
    Parameters
    ----------
    spec : 2darray
        The spectrum to plot
    sr : float
        Sample Rate (ADC)
    cf : float
        Central Frequency
    title : str
        The title of the plot. 
    imshow_scale : tuple
        Two tuple of floats. The first one sets the min 
        value to display, the second sets max value.
    cmap : str
        Name of the pyplot colormap.
    """
    if title is None:
        title=f"Central Freq {cf/1e6:.0f}MHz, Sample Rate {sr/1e6:.0f}MHz"
    nframes,nchan=spec.shape
    lframe=2*(nchan-1)
    fig,ax=plt.subplots(figsize=(6,6))
    log_spec = np.log(abs(spec)+1e-16) # add some noise for plotting purposes
    
    # Set the color scale by "modifying" spectrum (purely for visuals)
    log_spec[0,0]=imshow_scale[1] # Hack, set first pixel to cieling
    log_spec[0,1]=imshow_scale[0] # Hack, set second pixel to floor
    if (log_spec>imshow_scale[1]).any():
        print("WARNiNG: Spectrum has higher ceiling than is displayed!")
    log_spec[np.where(log_spec>imshow_scale[1])] = imshow_scale[1]
    log_spec[np.where(log_spec<imshow_scale[0])] = imshow_scale[0]
    
    freqs=fftshift(fftfreq(lframe,d=1/sr))[::2] + cf
    im = ax.imshow(log_spec,cmap=cmap)
    plt.title(title,fontsize=18)
    ax.set_xlabel("Frequency MHz")
    # plt.xticks(freqs)
    xticks=np.arange(0,len(freqs),len(freqs)//6)
    ax.set_xticks(xticks)
    ax.set_xticklabels(["{:.1f}".format(i) for i in freqs[xticks]/1e6])

    ax.set_ylabel("Time (s)")
    yticks=np.arange(0,nframes,nframes//6)
    
    # colorbar stuff
    divider=make_axes_locatable(ax)
    cax = divider.append_axes('right',size='5%',pad=0.05)
    fig.colorbar(im,cax,orientation='vertical')
    
    ax.set_yticks(yticks)
    ax.set_yticklabels(["{:.2f}".format(i) for i in yticks * lframe/sr])
    
    plt.tight_layout()
    plt.show()

Load the signal¶

In [5]:
# Load from raw file
def load_sig(path:str, verbose=False):
    """Load the signal from binary file located at path"""
    sig=np.fromfile(path,dtype="float32") # load signal from file
    sig=(sig-sig.mean())/sig.std() # normalize
    sig=sig[LFRAME*NFRAMES_OFFSET:(NFRAMES+NFRAMES_OFFSET)*LFRAME] # trim signal
    sigadc=quantize_8_bit_real(sig,delta=ADC_DELTA) # ADC quantize signal
    if verbose is True:
        plt.figure()
        plt.plot(sig[:512],label="RAW")
        plt.plot(sigadc[:512],linewidth=1.5,label="ADC")
        plt.legend()
        plt.tight_layout()
        plt.show()
    return sigadc
sig=load_sig(FNAME)
# nframe_full is global! 
nframe_full=len(sig)//LFRAME # number of frames in full signal
sig=sig[:(len(sig)//LFRAME)*LFRAME] # trunkate signal

Channelize and Quantize¶

In [6]:
# Get the full channelized signal (for later)
spec_adc_full=forward_pfb(sig,NCHAN,NTAP)
# Quantize the spectrum, 4+4bits=1byte (real+imag)
spec_adc_full_q,std_per_chan=quantize_8_bit_spec_scaled_per_channel(
        spec_adc_full, COMPLEX_DELTA)
del spec_adc_full # don't need this, takes up lots of memory
In [7]:
# Display channelized signal, U=1
u=1
# Get spectrum and plot it
spec_adc_u1=forward_pfb(sig[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_adc_u1/sqrt(u*LFRAME), # normalize spectrum
          SR,CF,title=f"Channelized ADC'd E-field U={u}")
# Get 4+4 bit quantized spectrum and plot residuals
spec_adc_u1_q,_=quantize_8_bit_spec_scaled_per_channel(
                    spec_adc_u1, COMPLEX_DELTA)
waterfall((spec_adc_u1_q-spec_adc_u1)/spec_adc_u1.std(axis=0), SR, CF, 
          title=f"Channelized ADC'd E-field U={u}\
\n4+4 bit-quantized, Residuals\
\n(normalized by power in each channel)",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [8]:
# Display channelized signal, U=2
u=2
# Get spectrum, plot it
spec_adc_u2=forward_pfb(sig[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_adc_u2/sqrt(u*LFRAME),
          SR, CF,title=f"Channelized ADC'd E-field U={u}")
# Quantize spectrum, plot residuals
spec_adc_u2_q,_=quantize_8_bit_spec_scaled_per_channel(
                    spec_adc_u2, COMPLEX_DELTA)
waterfall((spec_adc_u2_q-spec_adc_u2)/spec_adc_u2.std(axis=0),
         SR, CF, title=f"Channelized ADC'd E-field U={u}\
\n4+4 bit quantized, Residuals\
\n(normalized by power in each channel)",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [9]:
# Display channelized signal, U=4
u=4
# Get spectrum, plot it
spec_adc_u4=forward_pfb(sig[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_adc_u4/sqrt(u*LFRAME),
          SR, CF,title=f"Channelized ADC'd E-field U={u}")
# Quantize spectrum, plot diff (residuals)
spec_adc_u4_q,_=quantize_8_bit_spec_scaled_per_channel(
                    spec_adc_u4, COMPLEX_DELTA)
waterfall((spec_adc_u4_q-spec_adc_u4)/spec_adc_u4.std(axis=0),
         SR, CF, title=f"Channelized ADC'd E-field U={u}\
\n4+4 bit quantized, residuals\
\n(normalized by power in each channel)",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!

Re-channelize naivly¶

Invert the PFB naively (without filter)¶
In [10]:
sig_ipfb=inverse_pfb(spec_adc_full_q) # Apply inverse PFB
sig_ipfb,imag = sig_ipfb.real,sig_ipfb.imag # Drop the imaginary part
print(f"Sanity check: {sig_ipfb.std()} >> {imag.std()}")
del imag # delete this variable to clear memory
Sanity check: 1.0194471261087377 >> 1.8295780703350323e-16
In [11]:
# Display channelized signal, U=1
u=1
spec_ipfb_u1=forward_pfb(sig_ipfb[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_ipfb_u1/sqrt(u*LFRAME),
          SR, CF,title=f"Channelized IPFB'd signal U={u}")
waterfall((spec_ipfb_u1-spec_adc_u1_q)/spec_adc_u1_q.std(axis=0),
         SR, CF,title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
Re-channelize signal with U=2,4, display residuals¶
In [12]:
# Display re-channelized signal, U=2
u=2
spec_ipfb_u2=forward_pfb(sig_ipfb[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_ipfb_u2/sqrt(u*LFRAME),
         SR, CF, title=f"Re-Channelized IPFB'd signal U={u}")
waterfall((spec_ipfb_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
         SR, CF, title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [13]:
# Display re-channelized signal, U=4
u=4
spec_ipfb_u4=forward_pfb(sig_ipfb[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_ipfb_u4/sqrt(u*LFRAME),
         SR, CF, title=f"Re-Channelized IPFB'd signal U={u}")
waterfall((spec_ipfb_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
         SR, CF, title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!

re-channelize with Wiener filter¶

Apply IPFB with Wiener filter¶
In [14]:
sig_wien=inverse_pfb(spec_adc_full_q, wiener_thresh=0.1) # Apply inverse PFB
sig_wien,imag = sig_wien.real,sig_wien.imag # Drop the imaginary part
print(f"Sanity check: {sig_wien.std()} >> {imag.std()}")
del imag # delete this variable to clear memory
Sanity check: 0.9906092816117328 >> 1.7893473424362953e-16
In [15]:
# Display channelized signal, U=1
u=1
spec_wien_u1=forward_pfb(sig_wien[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_wien_u1/sqrt(u*LFRAME),
          SR, CF,title=f"Channelized IPFB'd\nWiener-filtred signal U={u}")
waterfall((spec_wien_u1-spec_adc_u1_q)/spec_adc_u1_q.std(axis=0),
         SR, CF,title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
Re-channelize signal with U=2, 4, and display¶
In [16]:
# Display re-channelized signal, U=2
u=2
spec_wien_u2=forward_pfb(sig_wien[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_wien_u2/sqrt(u*LFRAME),
          SR, CF, 
          title=f"Re-Channelized IPFB'd\nWiener-filtered signal U={u}")
waterfall((spec_wien_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF, title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [17]:
# Display re-channelized signal, U=2
u=4
spec_wien_u4=forward_pfb(sig_wien[:1024*u*u*LFRAME],(NCHAN-1)*u+1,NTAP)
waterfall(spec_wien_u4/sqrt(u*LFRAME),
          SR, CF, 
          title=f"Re-Channelized IPFB'd\nWiener-filtered signal U={u}")
waterfall((spec_wien_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF, title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!

Re-channelize with extra information¶

From IPFB Wiener, do CG-descent with no prior¶
In [18]:
# Construct B operator and u vector without a prior
B,u = cg.get_Bu_noprior(spec_adc_full_q,
                                delta=COMPLEX_DELTA,
                                ntap=NTAP)

# CG descent onto reconstructed timestream without prior
sig_cg_noprior=cg.conjugate_gradient_descent(B,u,x0=sig_wien,
                                             x_true=sig,
                                             max_iter=5, 
                                             verbose=True,
                                             k=nframe_full,
                                             rmin=0)
INFO: Conjugate Gradient descent completed.
From IPFB Wiener, do CG-descent with 5% extra info¶
In [19]:
# Load 5% indices that make up your prior
# (with 5%, best result npersave=2, max_iter=1)
_,saved_idxs_5perc=cg.get_saved_idxs(n_per_save=2, prct=0.05,
                                   k=nframe_full, lblock=LFRAME)

# Construct B operator and u vector using prior
B,u,chisq = cg.get_Bu_withprior(sig, spec_adc_full_q,
                                delta=COMPLEX_DELTA, 
                                saved_idxs=saved_idxs_5perc,
                                ntap=NTAP)

# CG descend onto reconstructed timestream `ipfb_cg`
sig_cg_5perc=cg.conjugate_gradient_descent(B,u,x0=sig_wien,
                                           x_true=sig,
                                           max_iter=1,
                                           verbose=True,
                                           k=nframe_full,
                                           rmin=0)
INFO: Conjugate Gradient descent completed.
In [20]:
# Display channelized signal, U=1
u=1
spec_cg_5perc_u1=forward_pfb(sig_cg_5perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_5perc_u1/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 5% U={u}")
waterfall((spec_cg_5perc_u1-spec_adc_u1_q)/spec_adc_u1_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
In [21]:
# Display channelized signal, U=2
u=2
spec_cg_5perc_u2=forward_pfb(sig_cg_5perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_5perc_u2/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 5% U={u}")
waterfall((spec_cg_5perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [22]:
# Display channelized signal, U=4
u=4
spec_cg_5perc_u4=forward_pfb(sig_cg_5perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_5perc_u4/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 5% U={u}")
waterfall((spec_cg_5perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
From IPFB Wiener, do CG-descent with 10% extra info¶
In [23]:
# Load 5% indices that make up your prior
# (with 5%, best result npersave=1, max_iter=1 (confusingly means 1step))
_,saved_idxs_10perc=cg.get_saved_idxs(n_per_save=1, prct=0.10,
                                   k=nframe_full, lblock=LFRAME)

# Construct B operator and u vector using prior
B,u,chisq = cg.get_Bu_withprior(sig, spec_adc_full_q,
                                delta=COMPLEX_DELTA, 
                                saved_idxs=saved_idxs_10perc,
                                ntap=NTAP)

# CG descend onto reconstructed timestream `ipfb_cg`
sig_cg_10perc=cg.conjugate_gradient_descent(B,u,x0=sig_wien,
                                           x_true=sig,
                                           max_iter=1,
                                           verbose=True,
                                           k=nframe_full,
                                           rmin=0)
INFO: Conjugate Gradient descent completed.
In [24]:
# Display channelized signal, U=1
u=1
spec_cg_10perc_u1=forward_pfb(sig_cg_10perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_10perc_u1/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 10% U={u}")
waterfall((spec_cg_10perc_u1-spec_adc_u1_q)/spec_adc_u1_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [25]:
# Display channelized signal, U=2
u=2
spec_cg_10perc_u2=forward_pfb(sig_cg_10perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_10perc_u2/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 10% U={u}")
waterfall((spec_cg_10perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [26]:
# Display channelized signal, U=4
u=4
spec_cg_10perc_u4=forward_pfb(sig_cg_10perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_10perc_u4/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 10% U={u}")
waterfall((spec_cg_10perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
From IPFB Wiener, do CG-descent with 20% extra info¶
In [27]:
# Load 5% indices that make up your prior
# (with 5%, best result npersave=2, max_iter=2 (confusingly means 1step))
_,saved_idxs_20perc=cg.get_saved_idxs(n_per_save=1, prct=0.20,
                                   k=nframe_full, lblock=LFRAME)

# Construct B operator and u vector using prior
B,u,chisq = cg.get_Bu_withprior(sig, spec_adc_full_q,
                                delta=COMPLEX_DELTA, 
                                saved_idxs=saved_idxs_20perc,
                                ntap=NTAP)

# CG descend onto reconstructed timestream `ipfb_cg`
sig_cg_20perc=cg.conjugate_gradient_descent(B,u,x0=sig_wien,
                                           x_true=sig,
                                           max_iter=1,
                                           verbose=True,
                                           k=nframe_full,
                                           rmin=0)
INFO: Conjugate Gradient descent completed.
In [28]:
# Display channelized signal, U=1
u=1
spec_cg_20perc_u1=forward_pfb(sig_cg_20perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_20perc_u1/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 20% U={u}")
waterfall((spec_cg_20perc_u1-spec_adc_u1_q)/spec_adc_u1_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [29]:
# Display channelized signal, U=2
u=2
spec_cg_20perc_u2=forward_pfb(sig_cg_20perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_20perc_u2/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 20% U={u}")
waterfall((spec_cg_20perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [30]:
# Display channelized signal, U=2
u=4
spec_cg_20perc_u4=forward_pfb(sig_cg_20perc[:1024*u*u*LFRAME],
                          (NCHAN-1)*u+1, NTAP)
waterfall(spec_cg_20perc_u4/sqrt(u*LFRAME),
          SR, CF,
          title=f"Channelized CG 20% U={u}")
waterfall((spec_cg_20perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, normalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!

Compare and Contrast Residuals¶

up-channelize by 2x, i.e. U=2¶

In [31]:
# IPFB
waterfall((spec_ipfb_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF, title=f"Residuals, IPFB'd naively\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# Wiener filter
waterfall((spec_wien_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF, title=f"Residuals, Wiener Filtered\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 5% extra timestream data saved
waterfall((spec_cg_5perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 5% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 10% extra timestream data saved
waterfall((spec_cg_10perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 10% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 20% extra timestream data saved
waterfall((spec_cg_20perc_u2-spec_adc_u2_q)/spec_adc_u2_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 20% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!

up-channelize by 4x, i.e. U=4¶

In [32]:
# IPFB
waterfall((spec_ipfb_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF, title=f"Residuals, IPFB'd naively\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# Wiener filter
waterfall((spec_wien_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF, title=f"Residuals, Wiener Filtered\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 5% extra timestream data saved
waterfall((spec_cg_5perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 5% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 10% extra timestream data saved
waterfall((spec_cg_10perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 10% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)

# 20% extra timestream data saved
waterfall((spec_cg_20perc_u4-spec_adc_u4_q)/spec_adc_u4_q.std(axis=0),
          SR, CF,
          title=f"Residuals, CG 20% data saved\
\nnormalized by channel",
          imshow_scale=IMSCALE_RES,cmap=CMAP_RES)
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
WARNiNG: Spectrum has higher ceiling than is displayed!
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: